/**
 * Chart.js 数据可视化工具类
 * 支持折线图、柱状图、饼图、环形图、雷达图等多种图表类型
 * 提供颜色生成、数据更新、图表交互等功能
 */
class ChartUtils {
    /**
     * 获取默认图表配置
     * @returns {Object} 基础图表配置
     */
    static get DEFAULT_OPTIONS() {
        return {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    position: 'top',
                    labels: {
                        usePointStyle: true,
                        padding: 15
                    }
                },
                tooltip: {
                    backgroundColor: 'rgba(0, 0, 0, 0.7)',
                    titleColor: '#fff',
                    bodyColor: '#fff',
                    borderColor: 'rgba(255, 255, 255, 0.2)',
                    borderWidth: 1,
                    padding: 12,
                    cornerRadius: 6,
                    displayColors: true,
                    callbacks: {
                        label: function(context) {
                            return context.label + ': ' + context.raw;
                        }
                    }
                }
            },
            animation: {
                duration: 1000,
                easing: 'easeOutQuart'
            }
        };
    }

    /**
     * 获取画布上下文
     * @param {string} canvasId 画布元素ID
     * @returns {CanvasRenderingContext2D} 画布上下文
     * @throws {Error} 当画布元素不存在时抛出错误
     */
    static _getCanvasContext(canvasId) {
        const canvas = document.getElementById(canvasId);
        if (!canvas) {
            throw new Error(`画布元素不存在，ID: ${canvasId}`);
        }
        return canvas.getContext('2d');
    }

    /**
     * 创建图表实例
     * @param {string} type 图表类型(line, bar, pie, doughnut, radar, polarArea)
     * @param {string} canvasId 画布元素ID
     * @param {Object} data 图表数据
     * @param {Object} options 自定义配置
     * @returns {Chart} Chart.js实例
     */
    static createChart(type, canvasId, data, options = {}) {
        const ctx = this._getCanvasContext(canvasId);
        
        // 合并默认配置、类型特定配置和自定义配置
        const mergedOptions = {
            ...this.DEFAULT_OPTIONS,
            ...this._getTypeSpecificOptions(type),
            ...options
        };
        
        return new Chart(ctx, {
            type,
            data,
            options: mergedOptions
        });
    }

    /**
     * 获取特定图表类型的配置
     * @param {string} type 图表类型
     * @returns {Object} 类型特定配置
     */
    static _getTypeSpecificOptions(type) {
        const baseScales = {
            x: {
                grid: {
                    display: false
                }
            },
            y: {
                beginAtZero: true,
                grid: {
                    color: 'rgba(0, 0, 0, 0.05)'
                }
            }
        };
        
        switch (type) {
            case 'line':
                return {
                    scales: baseScales,
                    interaction: {
                        mode: 'index',
                        intersect: false
                    },
                    elements: {
                        line: {
                            tension: 0.3,
                            borderWidth: 3
                        },
                        point: {
                            radius: 4,
                            hoverRadius: 6
                        }
                    }
                };
            case 'bar':
                return {
                    scales: baseScales,
                    indexAxis: 'x',
                    elements: {
                        bar: {
                            borderRadius: 4
                        }
                    }
                };
            case 'pie':
            case 'doughnut':
                return {
                    cutout: type === 'doughnut' ? '65%' : '0%',
                    plugins: {
                        legend: {
                            position: 'right'
                        }
                    }
                };
            case 'radar':
                return {
                    scales: {
                        r: {
                            beginAtZero: true,
                            grid: {
                                color: 'rgba(0, 0, 0, 0.05)'
                            },
                            angleLines: {
                                color: 'rgba(0, 0, 0, 0.1)'
                            }
                        }
                    }
                };
            default:
                return {};
        }
    }

    /**
     * 创建折线图
     * @param {string} canvasId 画布元素ID
     * @param {Object} data 图表数据
     * @param {Object} options 自定义配置
     * @returns {Chart} Chart.js实例
     */
    static createLineChart(canvasId, data, options = {}) {
        return this.createChart('line', canvasId, data, options);
    }

    /**
     * 创建柱状图
     * @param {string} canvasId 画布元素ID
     * @param {Object} data 图表数据
     * @param {Object} options 自定义配置
     * @returns {Chart} Chart.js实例
     */
    static createBarChart(canvasId, data, options = {}) {
        return this.createChart('bar', canvasId, data, options);
    }

    /**
     * 创建饼图
     * @param {string} canvasId 画布元素ID
     * @param {Object} data 图表数据
     * @param {Object} options 自定义配置
     * @returns {Chart} Chart.js实例
     */
    static createPieChart(canvasId, data, options = {}) {
        return this.createChart('pie', canvasId, data, options);
    }

    /**
     * 创建环形图
     * @param {string} canvasId 画布元素ID
     * @param {Object} data 图表数据
     * @param {Object} options 自定义配置
     * @returns {Chart} Chart.js实例
     */
    static createDoughnutChart(canvasId, data, options = {}) {
        return this.createChart('doughnut', canvasId, data, options);
    }

    /**
     * 创建雷达图
     * @param {string} canvasId 画布元素ID
     * @param {Object} data 图表数据
     * @param {Object} options 自定义配置
     * @returns {Chart} Chart.js实例
     */
    static createRadarChart(canvasId, data, options = {}) {
        return this.createChart('radar', canvasId, data, options);
    }

    /**
     * 生成图表颜色
     * @param {number} count 颜色数量
     * @param {number} alpha 透明度(0-1)
     * @param {boolean} isGradient 是否生成渐变色
     * @returns {string[]} 颜色数组
     */
    static generateColors(count, alpha = 1, isGradient = false) {
        const baseColors = [
            'rgba(54, 162, 235, ${alpha})',  // 蓝色
            'rgba(75, 192, 192, ${alpha})',  // 绿色
            'rgba(255, 99, 132, ${alpha})',  // 红色
            'rgba(255, 159, 64, ${alpha})',  // 橙色
            'rgba(255, 206, 86, ${alpha})',  // 黄色
            'rgba(153, 102, 255, ${alpha})',  // 紫色
            'rgba(231, 233, 237, ${alpha})'   // 灰色
        ];
        
        const colors = [];
        for (let i = 0; i < count; i++) {
            const color = baseColors[i % baseColors.length].replace('${alpha}', alpha);
            colors.push(color);
        }
        
        // 生成渐变色（简化实现）
        if (isGradient && count > 1) {
            return this._generateGradientColors(colors, count);
        }
        
        return colors;
    }

    /**
     * 生成渐变色（内部方法）
     * @param {string[]} baseColors 基础颜色数组
     * @param {number} count 颜色数量
     * @returns {string[]} 渐变色数组
     */
    static _generateGradientColors(baseColors, count) {
        // 实际项目中应解析RGBA值并插值生成渐变色
        return baseColors;
    }

    /**
     * 动态更新图表数据
     * @param {Chart} chart Chart实例
     * @param {Object} newData 新数据
     * @param {boolean} isMerge 是否合并数据
     * @throws {Error} 当Chart实例无效时抛出错误
     */
    static updateChartData(chart, newData, isMerge = true) {
        if (!chart || !chart.data) {
            throw new Error('无效的Chart实例，无法更新数据');
        }
        
        if (isMerge) {
            chart.data = {
                ...chart.data,
                ...newData
            };
        } else {
            chart.data = newData;
        }
        
        chart.update();
    }

    /**
     * 销毁图表实例
     * @param {Chart} chart Chart实例
     */
    static destroyChart(chart) {
        if (chart && chart.destroy) {
            chart.destroy();
        }
    }

    /**
     * 重置图表尺寸
     * @param {Chart} chart Chart实例
     */
    static resizeChart(chart) {
        if (!chart || !chart.canvas) return;
        // 触发resize事件以适应容器大小
        const event = new Event('resize');
        window.dispatchEvent(event);
        chart.resize();
    }

    /**
     * 生成指定数量的随机颜色
     * @param {number} count 颜色数量
     * @param {number} alpha 透明度(0-1)
     * @returns {string[]} 颜色数组
     */
    static generateColors(count, alpha = 0.7) {
        const colors = [];
        const hueStep = 360 / count;
        
        for (let i = 0; i < count; i++) {
            const hue = i * hueStep;
            colors.push(`hsla(${hue}, 70%, 60%, ${alpha})`);
        }
        
        return colors;
    }

    /**
     * 创建折线图
     * @param {string} canvasId 画布ID
     * @param {object} data 图表数据
     * @param {object} options 图表选项
     * @returns {Chart} Chart实例
     */
    static createLineChart(canvasId, data, options = {}) {
        const ctx = document.getElementById(canvasId).getContext('2d');
        
        // 默认配置
        const defaultOptions = {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                x: {
                    grid: {
                        display: false
                    }
                },
                y: {
                    beginAtZero: true
                }
            }
        };
        
        // 合并用户选项和默认选项
        const mergedOptions = { ...defaultOptions, ...options };
        
        return new Chart(ctx, {
            type: 'line',
            data: data,
            options: mergedOptions
        });
    }

    /**
     * 更新图表数据
     * @param {Chart} chart Chart实例
     * @param {object} newData 新数据对象
     */
    static updateChartData(chart, newData) {
        if (!chart || !chart.data) {
            throw new Error('无效的Chart实例');
        }
        
        // 更新数据集
        if (newData.datasets) {
            newData.datasets.forEach((dataset, index) => {
                if (chart.data.datasets[index]) {
                    Object.assign(chart.data.datasets[index], dataset);
                } else {
                    chart.data.datasets.push(dataset);
                }
            });
        }
        
        // 更新标签
        if (newData.labels) {
            chart.data.labels = newData.labels;
        }
        
        chart.update();
    }

    /**
     * 导出图表为图片
     * @param {Chart} chart Chart实例
     * @param {string} format 图片格式(png, jpeg)
     * @returns {string} 图片DataURL
     * @throws {Error} 当Chart实例无效或格式不支持时抛出错误
     */
    static exportChartAsImage(chart, format = 'png') {
        if (!chart || !chart.toBase64Image) {
            throw new Error('无效的Chart实例，无法导出图片');
        }
        
        const validFormats = ['png', 'jpeg'];
        if (!validFormats.includes(format.toLowerCase())) {
            throw new Error(`不支持的图片格式: ${format}，支持格式: ${validFormats.join(', ')}`);
        }
        
        return chart.toBase64Image(`image/${format}`, 1.0);
    }
}

// DOM加载完成后初始化图表
document.addEventListener('DOMContentLoaded', function() {
    // 检查Chart.js是否已加载
    if (typeof Chart === 'undefined') {
        console.error('未找到Chart.js库，请在本脚本前引入Chart.js');
        return;
    }

    // 自动初始化带有数据属性的画布元素
    document.querySelectorAll('[data-chart-type]').forEach(canvas => {
        try {
            const chartType = canvas.getAttribute('data-chart-type');
            const chartData = JSON.parse(canvas.getAttribute('data-chart-data'));
            const chartOptions = canvas.hasAttribute('data-chart-options') 
                ? JSON.parse(canvas.getAttribute('data-chart-options')) 
                : {};

            // 支持的图表类型
            const supportedTypes = ['line', 'bar', 'pie', 'doughnut', 'radar'];
            if (!supportedTypes.includes(chartType)) {
                console.warn(`不支持的图表类型: ${chartType}，支持类型: ${supportedTypes.join(', ')}`);
                return;
            }

            // 使用对应方法创建图表
            const createMethod = `create${chartType.charAt(0).toUpperCase() + chartType.slice(1)}Chart`;
            ChartUtils[createMethod](canvas.id, chartData, chartOptions);
        } catch (error) {
            console.error('图表初始化失败:', error);
        }
    });
});